package com.xiaoshuidi.cloud.module.rooms.job.delayjob.strategy;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomel.vo.RoomelUpdateReqVO;
import com.xiaoshuidi.cloud.module.rooms.enums.RentStatusEnum;
import com.xiaoshuidi.cloud.module.rooms.enums.RoomHouseReservePaymentStatus;
import com.xiaoshuidi.cloud.module.rooms.enums.RoomHouseReserveStatus;
import com.xiaoshuidi.cloud.module.rooms.mq.producer.ReserveProducer;
import com.xiaoshuidi.cloud.module.rooms.mq.producer.RoomEsProducer;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouse;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomHouseReserve;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomStateRecord;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomHouseReserveRepository;
import com.xiaoshuidi.cloud.module.rooms.repository.RoomStateRecordRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.xiaoshuidi.cloud.module.rooms.enums.ErrorCodeConstants.RESERVE_INFO_NOT_EXISTS;

/**
 * 预定失效日期到期处理
 */
@Slf4j
@Component
public class ExpirationDateStrategy implements IStrategy{

    @Resource
    private RoomHouseReserveRepository reserveRepository;
    @Resource
    private RoomHouseRepository roomHouseRepository;
    @Resource
    private RoomEsProducer roomEsProducer;
    @Resource
    private RoomStateRecordRepository roomStateRecordRepository;
    @Resource
    private ReserveProducer reserveProducer;
    private static String reservedCancelReason = "已支付到期取消";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void consumerTask(Object taskParam) {
        log.info("预定失效日期到期处理:{}", JsonUtils.toJsonString(taskParam));
        Long id = (Long) taskParam;
        RoomHouseReserve roomHouseReserve = reserveRepository.getById(id);
        if(ObjectUtil.isEmpty(roomHouseReserve)){
            throw new ServiceException(RESERVE_INFO_NOT_EXISTS);
        }
        if(!roomHouseReserve.getStatus().equals(RoomHouseReserveStatus.RESERVED.getCode())){
            return;
        }
        String expireTime = LocalDateTimeUtil.format(roomHouseReserve.getExpirationDate(), "yyyy-MM-dd HH:mm");
        String excuteTime = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm");
        log.info("到期时间:{}, 当前时间:{}", expireTime, excuteTime);
        if(!expireTime.equals(excuteTime)){
            return;
        }
        roomHouseReserve.setStatus(RoomHouseReserveStatus.FAILURE.getCode());
        roomHouseReserve.setCancelTime(LocalDateTime.now());
        roomHouseReserve.setCancelReason(reservedCancelReason);
        roomHouseReserve.setPaymentStatus(RoomHouseReservePaymentStatus.CANCELED.getCode());
        reserveRepository.updateById(roomHouseReserve);

        RoomHouse roomHouse = new RoomHouse();
        roomHouse.setId(roomHouseReserve.getRoomHouseId());
        roomHouse.setIsLock(Boolean.FALSE);
        roomHouseRepository.updateById(roomHouse);

        List<RoomelUpdateReqVO> roomEsVoList = new ArrayList<>();
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseReserve.getRoomHouseId());
        roomelUpdateReqVO.setIsScheduled(Boolean.FALSE);

        //处理房态, 查询当前房间的当前房态
        List<RoomStateRecord> roomStateRecords = roomStateRecordRepository.getStatesByRoomIdAndIsCurrentState(roomHouseReserve.getRoomHouseId());
        //回滚房态到预定的前置房态, 空房 | 入住中
        RoomStateRecord stateRecord = roomStateRecords.stream().filter(record -> RentStatusEnum.SCHEDULED.getValue().equals(record.getState())).findFirst().orElse(null);
        if (stateRecord != null) {
            stateRecord.setIsCurrentState(false);
            roomStateRecordRepository.updateById(stateRecord);
        }
        Optional<RoomStateRecord> stayingInRecord = roomStateRecords.stream().filter(record -> RentStatusEnum.STAYINGIN.getValue().equals(record.getState())).findFirst();
        if (!stayingInRecord.isPresent()) {
            RoomStateRecord currentStateRecord = new RoomStateRecord();
            currentStateRecord.setIsCurrentState(Boolean.TRUE)
                    .setState(RentStatusEnum.EMPTY.getValue())
                    .setRoomId(roomHouseReserve.getRoomHouseId())
                    .setBeforeState(RentStatusEnum.SCHEDULED.getValue())
                    .setTenantId(roomHouseReserve.getTenantId());
            roomStateRecordRepository.save(currentStateRecord);
            roomelUpdateReqVO.setHouseState(RentStatusEnum.EMPTY.getValue());
        } else {
            roomelUpdateReqVO.setHouseState(RentStatusEnum.STAYINGIN.getValue());
        }
        roomEsVoList.add(roomelUpdateReqVO);

        reserveProducer.paymentCancel(roomHouseReserve.getId(), roomHouseReserve.getTenantId(), roomHouseReserve.getBookerId(), roomHouse.getApartmentId());
        //推动ES状态
        roomEsProducer.updateBatchRoomEl(roomEsVoList);
    }
}
